﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
using Veracruz.IdentityModel;
using Microsoft.IdentityModel.Claims;
using System.Web;
using System.Configuration.Provider;
using System.Globalization;

namespace Veracruz.Providers
{
    /// <summary>
    /// ASPNet role provider based on Veracruz claims
    /// </summary>
    public sealed class ClaimBasedRoleProvider
        : RoleProvider
    {
        #region fields
        private bool _isInitialized = false;
        #endregion

        #region ctor
        public ClaimBasedRoleProvider()
        {

        }
        #endregion

        #region props
        public override string ApplicationName { get; set; }
        #endregion

        #region methods
        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            base.Initialize(name, config);
            _isInitialized = true;
        }
        public override string[] GetAllRoles()
        {
            if (!_isInitialized)
            {
                throw new InvalidOperationException("RoleProvider_Not_initialized");
            }

            return RoleClaimDefinitions.GetAllRoles().ToArray();
        }
        public override string[] GetRolesForUser(string username)
        {
            if (!_isInitialized)
            {
                throw new InvalidOperationException("RoleProvider_Not_initialized");
            }

            //IClaimsPrincipal __claims = HttpContext.Current.User as IClaimsPrincipal;
            IClaimsIdentity __identity = HttpContext.Current.User.Identity as IClaimsIdentity;

            if (__identity == null)
            {
                throw new ProviderException("InvalidIdentity");
            }

            if (!__identity.IsAuthenticated)
            {
                throw new ProviderException("RoleProvider_User_Not_Authenticated");
            }

            if (!username.Equals(__identity.Name))
            {
                throw new ProviderException(string.Format("ExceptionRoleProviderUserNameMismatch username:{0} identityName:{1}", username, __identity.Name));
            }


            List<Microsoft.IdentityModel.Claims.Claim> __roleClaims = new List<Microsoft.IdentityModel.Claims.Claim>(__identity.Claims.FindAll(c => c.ClaimType == RoleClaimDefinitions.ClaimType));
            return __roleClaims.ConvertAll<string>(c => c.Value).ToArray();
        }
        public override bool IsUserInRole(string username, string roleName)
        {
            if (!_isInitialized)
            {
                throw new InvalidOperationException("RoleProvider_Not_initialized");
            }

            if (HttpContext.Current == null)
                return false;

            IClaimsIdentity __identity = HttpContext.Current.User.Identity as IClaimsIdentity;

            if (__identity == null)
            {
                throw new ProviderException("InvalidIdentity");
            }

            if (!__identity.IsAuthenticated)
            {
                throw new ProviderException("RoleProvider_User_Not_Authenticated");
            }

            if (!username.Equals(__identity.Name))
            {
                throw new ProviderException(string.Format("ExceptionRoleProviderUserNameMismatch username:{0} identityName:{1}", username, __identity.Name));
            }


            return __identity.Claims.Single(c => c.Value == roleName) != null;
        }
        public override bool RoleExists(string roleName)
        {
            return !String.IsNullOrEmpty(GetRoleClaims().Single(c => string.Compare(c, roleName, true, CultureInfo.InvariantCulture) == 0));
        }
        private ICollection<string> GetRoleClaims()
        {
            //TODO:  should be a call to a svc
            return RoleClaimDefinitions.GetAllRoles();
        }

        #region No implementation required for WSS
        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }
        public override void CreateRole(string roleName)
        {
            throw new NotImplementedException();
        }
        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            throw new NotImplementedException();
        }
        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            throw new NotImplementedException();
        }
        public override string[] GetUsersInRole(string roleName)
        {
            throw new NotImplementedException();
        }
        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }
        #endregion
        #endregion
    }
}